<?php
// 字符相关库

/*返回随机数*/
function suiji($prefix = "a"): string
{
    $no     = mt_rand() . time() . mt_rand();
    $string = hash_hmac('md5', $no, uniqid(), false);
    return $prefix . substr($string, 0, 15);
}

/*未设置函数*/
function kong($word)
{
    if ($word == "") {
        $html = "无";
    } else {
        $html = $word;
    }
    return $html;
}

function money($money): string
{
    if ($money == "") {
        $money = "0.00";
    }
    return "<b class='red'>￥" . $money . "</b>";
}

/*显示内容最前面一定数量的文字*/
function zishu($word, $num, $isSpan = true): string
{
    if (mb_strlen($word, 'utf8') > $num) {
        $dot = "...";
    } else {
        $dot = "";
    }
    $string = mb_substr(html_entity_decode($word), 0, $num, "utf-8") . $dot;
    return $isSpan ? "<span title='" . $word . "'>" . kong($string) . "</span>" : kong($string);
}

/*表单提交数据整理和防sql注入*/
function formSub($data): string
{
    $data = trim($data);                              //消除两边的空格
    $data = htmlentities($data, ENT_QUOTES, "utf-8"); //字符转换为 HTML 实体。
    //对单引号（'）双引号（"）反斜杠（\）NULL进行转义
    return addslashes($data);
}

function formSubArray($data): array|string
{
    if (is_array($data)) {
        $result = [];
        foreach ($data as $key => $value) {
            if (is_array($value)) {
                $result[$key] = formSubArray($value);
            } else {
                $result[$key] = formSub($value);
            }
        }
    } else {
        $result = formSub($data);
    }
    return $result;
}

/*内容格式化*/
function neirong($article): string
{
    $replace[1] = "/\n/";
    $replace[2] = "/【【/";
    $replace[3] = "/】】/";
    $replace[4] = "/《《/";
    $replace[5] = "/》》/";
    $class[1]   = "</p><p>";
    $class[2]   = "<span class='articleTitle1'>";
    $class[3]   = "<span>";
    $class[4]   = "<span class='articleTitle2'>";
    $class[5]   = "<span>";
    $p          = preg_replace($replace, $class, $article);
    return "<p>" . $p . "</p>";
}

/**
 * 模板函数
 *
 * @param array $params
 * @param string $path
 * @return string
 */
function template(array $params, string $path): string
{
    $fields = array_keys($params);
    $values = array_values($params);
    $keys   = [];
    foreach ($fields as $key) {
        $keys[] = '{{' . $key . '}}';
    }
    $fileName = serverRoot . 'templates/' . $path;
    if (file_exists($fileName)) {
        $string = file_get_contents($fileName);
        return str_replace($keys, $values, $string);
    } else {
        return '模板文件不存在';
    }
}

/**
 * 解析标签
 *
 * @param $string
 * @return array|string|string[]|null
 */
function parseLangTag($string)
{
    return preg_replace_callback('/{l\.(.*?)}/', 'langReplace', $string);
}


/**
 * 生成单行文本框
 *
 * @param array $data
 *   $data = array(
 *   "name" => "文本框name",
 *   "id" => "文本框id",
 *   "laydate" => [] //"调用laydate日历框架，数组内可以放一些额外参数",
 *   "data" => [] //生成data-key 参数 用于单个文本域更新时
 *   "title" => "文本框标题",
 *   "value" => "文本框value",
 *   "class" => "文本框的class",
 *   "click" => "鼠标点击事件函数名",
 *   "blur" => "元素失去焦点事件函数名",
 *   "keyup" => "某个键盘按键被松开时的函数名",
 *   "other" => "串联其他属性",
 *   );
 * @return string
 */
function text(array $data): string
{
    $attribute = $js = "";
    if (isset($data['id'])) {
        $attribute .= " id='" . $data['id'] . "' ";
    } elseif (array_key_exists("laydate", $data)) { //如果存在laydate键名
        $id        = $data['laydateId'] ?? suiji();
        $attribute .= " id='" . $id . "' ";
        $json      = "";
        foreach ((array)$data['laydate'] as $key => $value) {
            if (in_array($key, ['done', 'ready', 'change', 'mark', 'min', 'max'])) {
                $json .= "," . $key . ":" . $value;
            } else {
                $json .= "," . $key . ":'" . $value . "'";
            }
        }
        $js = "<script>$(function(){laydate.render({elem:'#" . $id . "'" . $json . ", trigger:'click'});});</script>";
    }
    if (isset($data['title']) && $data['title']) {
        // 替换多语言标签
        if (str_contains($data['title'], '{l.')) {
            $data['title'] = parseLangTag($data['title']);
        }
        $attribute .= "  placeholder='" . $data['title'] . "' title='" . $data['title'] . "' ";
    }
    if (isset($data['value']) && mb_strlen($data['value'], 'utf8') > 0) {
        $attribute .= " value='" . $data['value'] . "' ";
    }
    $data['class'] = $data['class'] ?? '';
    if (isset($data['unit'])) {//单位
        $data['class'] .= " layui-input form-control";
    }
    if ($data['class']) {
        $attribute .= " class='" . $data['class'] . "' ";
    }
    // 自定义data 参数
    if (isset($data['data']) && is_array($data['data'])) {
        foreach ($data['data'] as $key => $value) {
            $key       = trim($key);
            $value     = trim($value);
            $attribute .= " data-$key='$value' ";
        }
    }
    // 支持的类型
    $keys  = ['click', 'blur', 'keyup', 'change'];
    $array = array_intersect($keys, array_keys($data));
    foreach ($array as $key) {
        $temp = explode(',', $data[$key]);
        // 统计个数
        $length    = count($temp);
        $attribute .= ' on' . $key . '="' . $temp[0] . "(this";
        if ($length > 1) {
            for ($i = 1; $i < $length; $i++) {
                $temp[$i]  = trim(str_replace(['\'', '"'], '', $temp[$i]));
                $attribute .= ", '$temp[$i]'";
            }
        }
        $attribute .= ')"';
    }
    $type  = $data['type'] ?? 'text';
    $other = $data['other'] ?? '';

    $html  = "<input type='$type' name='{$data['name']}' autocomplete='off' " . $attribute . $other . ">" . $js;
    if (isset($data['unit'])) {
        //带单位的输入框
        $html = "<div class='input-group'>" . $html . "<span class='input-group-addon'>{$data['unit']}</span></div>";
    }
    //密码显示隐藏
    if($type == 'password'){
        $html = "<div class='password-container'>
                    ".$html."
                    <img class='toggle-password' onclick='togglePassword(this)' src='".root."img/svg/pass_hide.svg'>
                </div>";
    }

    return $html . "\n";
}

/**
 * 生成密码框
 *
 * @param array $data
 * @return string
 */
function password(array $data): string
{
    $data['type'] = 'password';
    return text($data);
}

/*生成隐藏域
$data = array(
    "name" => "隐藏域的name",
    "value" => "隐藏域的value",
);
*/
function hidden($data): string
{
    $data['type'] = 'hidden';
    return text($data);
}

/*生成多行文本框
$data = array(
    "name" => "文本框name",
    "id" => "文本框id",
    "title" => "文本框标题",
    "value" => "文本框value",
    "class" => "文本框的class",
);
*/
function textarea($data): string
{
    $id = '';
    if (isset($data['id']) && $data['id']) {
        $id = " id='" . $data['id'] . "' ";
    }
    $name          = getVal($data, 'name');
    $title         = getVal($data, 'title');
    $class         = getVal($data, 'class');
    $value         = getVal($data, 'value');
    $data['other'] = getVal($data, 'other');
    return "<textarea name='" . $name . "' " . $id . " {$data['other']} title='" . $title . "' placeholder='" . $title . "' class='" . $class . "'>" . $value . "</textarea>";
}

/*输出多选框
$data = array(
    "name" => "多选框名称",
    "value" => "数组，键名为多选框的value，键值为多选框的显示结果",
    "checked" => "数组，选中的多选框的value",
);
*/
function checkbox($data): string
{
    $html  = $checked = '';
    $other = $data['other'] ?? '';
    //标题
    if (isset($data['title'])) {
        if (array_values($data['value']) === $data['value'] and $data['value'] == $data['checked']) { //一维数组全选状态
            $checked = "checked";
        } elseif (isset($data['checked']) && array_keys($data['value']) == $data['checked']) { //二维数组全选状态
            $checked = "checked";
        }
        $html .= "<label class='checkbox'><input name='" . $data['name'] . "CheckAll' type='checkbox' value='" . $data['name'] . "' " . $checked . " onchange=\"checkboxAll(this)\"><span></span>&nbsp;" . $data['title'] . "：</label>";
    }
    //如果用此数组中所有的值组成的数组完全等于此数组，则说明此数组为索引数组，反之为关联数组
    if (array_values($data['value']) === $data['value']) {
        foreach ($data['value'] as $key) {
            if (isset($data['checked']) && in_array($key, $data['checked'])) {
                $checked = "checked";
            } else {
                $checked = "";
            }
            $html .= "<label class='checkbox'><input name='" . $data['name'] . "[]' type='checkbox' $other value='" . $key . "' " . $checked . "><span></span>&nbsp;" . $key . "</label>&nbsp;&nbsp;";
        }
    } else {
        foreach ($data['value'] as $key => $value) {
            if (isset($data['checked']) && in_array($key, (array)$data['checked'])) {
                $checked = "checked";
            } else {
                $checked = "";
            }
            $html .= "<label class='checkbox'><input name='" . $data['name'] . "[]' type='checkbox' $other value='" . $key . "' " . $checked . "><span></span>&nbsp;" . $value . "</label>&nbsp;&nbsp;";
        }
    }
    //返回
    return $html;
}

/*输出单选框
$data = array(
    "name" => "多选框名称",
    "value" => "数组，键名为单选框的value，键值为单选框的显示结果",
    "checked" => "选中的单选框的value",
    "change" => "选项发生改变时调用的js函数名称",
);
*/
function radio($data)
{
    $result = $change = $attribute = '';
    if (isset($data['change'])) {
        $change = " onchange='" . $data['change'] . "(this)' ";
    }
    // 自定义data 参数
    if (isset($data['data']) && is_array($data['data'])) {
        foreach ($data['data'] as $key => $value) {
            $key       = trim($key);
            $value     = trim($value);
            $attribute .= " data-$key='$value' ";
        }
    }
    if (isset($data['other'])) {
        $attribute .= ' ' . $data['other'];
    }
    $data['value'] = $data['value'] ?? $data['option'];
    //如果用此数组中所有的值组成的数组完全等于此数组，则说明此数组为索引数组，反之为关联数组
    if (array_values($data['value']) === $data['value']) {
        foreach ($data['value'] as $key) {
            if (isset($data['checked']) && $key == $data['checked']) {
                $checked = "checked";
            } else {
                $checked = "";
            }
            $result .= "<label class='radioLabel'>&nbsp;<input name='" . $data['name'] . "' type='radio' value='" . $key . "' " . $checked . $change . $attribute . ">&nbsp;" . $key . "</label>";
        }
    } else {
        foreach ($data['value'] as $key => $value) {
            if (isset($data['checked']) && $key == $data['checked']) {
                $checked = "checked";
            } else {
                $checked = "";
            }
            $result .= "<label class='radioLabel'>&nbsp;<input name='" . $data['name'] . "' type='radio' value='" . $key . "' " . $checked . $change . $attribute . ">&nbsp;" . $value . "</label>";
        }
    }
    return $result;
}


/**
 * option打印函数
 *
 * @param $data = array(
 *              "title" => "下拉菜单标题", 'null' => '禁用空选项'
 *              "option" => "option数组，键名为option的value，键值为option的显示结果",
 *              "value" => "option为selected时的value",
 *              );
 * @return string
 */
function option($data): string
{
    if (empty($data['title'])) {
        $result = "";
    } else {
        $attr   = !empty($data['null']) ? 'disabled' : '';
        $result = "<option value='' $attr>-" . $data['title'] . "-</option>";
    }
    //如果用此数组中所有的值组成的数组完全等于此数组，则说明此数组为索引数组，反之为关联数组
    if (array_values((array)$data['option']) === $data['option']) {
        foreach ($data['option'] as $key) {
            if (isset($data['value']) && $key == $data['value']) {
                $selected = " selected='selected' ";
            } else {
                $selected = "";
            }
            $result .= "<option value='$key' $selected>$key</option>";
        }
    } else {
        foreach ((array)$data['option'] as $key => $text) {
            if (isset($data['value']) && $key == $data['value']) {
                $selected = " selected='selected' ";
            } else {
                $selected = "";
            }
            $result .= "<option value='$key' $selected>$text</option>";
        }
    }
    return $result;
}

/**
 * 下拉菜单完整打印函数
 *
 * @param $data = array(
 *              "name" => "下拉菜单的name",
 *              "class" => "下拉菜单的class",
 *              "title" => "下拉菜单的标题",
 *              "id" => "下拉菜单的id",
 *              "option" => "下拉菜单的option数组，键名为option的value，键值为option的显示结果",
 *              "value" => "option为selected时的value",
 *              "change" => "下拉菜单选项发生改变时调用的js函数名称",
 *              "other" => "串联其他属性",
 *              'null' => '禁用空选项'
 *              );
 * @return string
 */
function select($data): string
{
    if (empty($data['name'])) {
        $html = "下拉菜单名称name没有定义";
    } else {
        $attribute = " name='" . $data['name'] . "' ";
        if (isset($data['class'])) {
            $attribute .= " class='" . $data['class'] . "' ";
        }
        if (isset($data['id'])) {
            $attribute .= " id='" . $data['id'] . "' ";
        }
        if (isset($data['other'])) {
            $attribute .= $data['other'];
        }
        // 自定义data 参数
        if (isset($data['data']) && is_array($data['data'])) {
            foreach ($data['data'] as $key => $value) {
                $key       = trim($key);
                $value     = trim($value);
                $attribute .= " data-$key='$value' ";
            }
        }
        // 支持的类型
        $keys  = ['change'];
        $array = array_intersect($keys, array_keys($data));
        foreach ($array as $key) {
            $temp = explode(',', $data[$key]);
            // 统计个数
            $length    = count($temp);
            $attribute .= ' on' . $key . '="' . $temp[0] . "(this";
            if ($length > 1) {
                for ($i = 1; $i < $length; $i++) {
                    $temp[$i]  = trim(str_replace(['\'', '"'], '', $temp[$i]));
                    $attribute .= ", '$temp[$i]'";
                }
            }
            $attribute .= ')"';
        }
        $data['title'] = $data['title'] ?? '';
        if (isset($data['title']) && $data['title']) {
            // 替换多语言标签
            if (str_contains($data['title'], '{l.')) {
                $data['title'] = parseLangTag($data['title']);
            }
        }
        $html = "
		<select " . $attribute . " title='".$data['title']."' >
		" . option([
                "title"  => $data['title'] ?: '请选择',
                'null'   => $data['null'] ?? false,
                "option" => $data['option'] ?? [],
                "value"  => getVal($data, 'value'),
            ]) . "
		</select>\n";
    }
    return $html;
}

/**
 *  下拉搜索查询多选或单选
 * $data = array(
 *   "name" => "下拉菜单的name",
 *   "class" => "下拉菜单的class",
 *   "title" => "下拉菜单的标题",
 *   "id" => "下拉菜单的id",
 *   "option" => "下拉菜单的option数组，键名为option的value，键值为option的显示结果",
 *   "value" => "option为selected时的value",
 *   "change" => "下拉菜单选项发生改变时调用的js函数名称",
 *   "multiple"=>"多项选择时值设为真"
 *  "table"=>"查询的表"
 *  "where"=>"查询的表的条件"
 *  "sqlId"=>"存储字段ID"
 *  "sqlField"=>"显示字段"
 * );
 */
function selectMultiple($data)
{
    $class = "";
    $id    = $change = $multiple = '';
    if (empty($data['name'])) {
        $html = "下拉菜单名称name没有定义";
    } else {
        $objId = suiji();
        if (isset($data['class'])) {
            $class = $data['class'];
        }
        if (isset($data['id'])) {
            $id = " id='" . $data['id'] . "' ";
        }
        if (isset($data['change'])) {
            $change = " onchange='" . $data['change'] . "(this)' ";
        }
        if (isset($data['multiple']) && $data['multiple'] === true) {
            $multiple = " multiple='multiple' ";
        }
        $field = (isset($data['field'])) ? $data['field'] : '*';

        $where = isset($data['where']) && !empty($data['where']) ? $data['where'] : ' 1=1 ';
        if (isset($data['table']) && isset($data['sqlField'])) {
            if ($data['table'] == 'staff') {
                $where = " workFlow ='已复核' and " . $where;
            }
            $all    = find(['table' => $data['table'], 'field' => $field, 'where' => $where]);
            $option = [];
            foreach ($all['array'] as $val) {
                if (isset($data['sqlId'])) {
                    $option[$val[$data['sqlId']]] = $val[$data['sqlField']];
                } else {
                    $option[] = $val[$data['sqlField']];
                }
            }
            $data['option'] = $option;
        }

        $class = $objId . ' ' . $class;
        $title = $data['title'] ?? '-请选择-';
        // 替换多语言标签
        if (str_contains($title, '{l.')) {
            $title = parseLangTag($title);
        }
        $other = $data['other'] ?? '';
        $value = $data['value'] ?? '';
        $html  = "
        <select class=\"$class\"  name='" . $data['name'] . "' title='" . $title . "' " . $id . $change . $multiple . $other . ">
        " . optionMultiple(["title" => $title, 'multiple' => $multiple, "option" => $data['option'], "value" => $value]) . "
        </select>\n
        <script>
        $(function() {
            $('.$objId').fSelect({class:'$class'});
        });
        </script>";
    }
    return $html;
}

/**
 * 选项
 *
 * @param $data
 * @return string
 */
function optionMultiple($data)
{
    if (empty($data['title'])) {
        $result = "";
    } else {
        $result = "<option value=''>-" . $data['title'] . "-</option>";
    }
    if (empty($data['multiple'])) {
        //下拉单选是赋值
        //如果用此数组中所有的值组成的数组完全等于此数组，则说明此数组为索引数组，反之为关联数组
        if (array_values((array)$data['option']) === $data['option']) {
            foreach ($data['option'] as $key) {
                if ($key == $data['value']) {
                    $selected = " selected='selected' ";
                } else {
                    $selected = "";
                }
                $result .= "<option value='$key' $selected>$key</option>";
            }
        } else {
            foreach ((array)$data['option'] as $key => $text) {
                if ($key == $data['value']) {
                    $selected = " selected='selected' ";
                } else {
                    $selected = "";
                }
                $result .= "<option value='$key' $selected>$text</option>";
            }
        }
    } else {
        //下拉多选时赋值
        $arr = explode(',', $data['value']);
        if (array_values((array)$data['option']) === $data['option']) {
            foreach ($data['option'] as $key) {
                foreach ($arr as $v) {
                    if ($key == $v) {
                        $selected = " selected='selected' ";
                        break;
                    } else {
                        $selected = "";
                    }
                }

                $result .= "<option value='$key' $selected>$key</option>";
            }
        } else {
            foreach ((array)$data['option'] as $key => $text) {
                foreach ($arr as $v) {
                    if ($key == $v) {
                        $selected = " selected='selected' ";
                        break;
                    } else {
                        $selected = "";
                    }
                }
                $result .= "<option value='$key' $selected>$text</option>";
            }
        }
    }
    return $result;
}


/*消除重复数据菜单
$data = array(
    "type" => "输出类型：select，option",
    "sqlForm" => "数据库表名，可带查询条件和排序等",
    "sqlField" => "需要排重的数据库表字段名"
    +函数select除option之外的所有参数
);
*/
function repeatSelect($data): string
{
    if (empty($data['sqlField'])) {
        $html = "排重关键字段名称为空";
    } elseif (empty($data['sqlForm'])) {
        $html = "数据库查询语句为空";
    } else {
        $option   = [];
        $sqlField = $data['sqlField'];
        $sql      = " SELECT DISTINCT " . $sqlField . " FROM " . $data['sqlForm'];
        $result   = sqlExec($sql, true);
        while ($array = mysqli_fetch_array($result)) {
            $key = $array[$sqlField];
            if (isset($key)) {
                $option[$key] = $key;
            }
        }
        unset($data['sqlField']);
        unset($data['sqlForm']);
        $data['option'] = $option;
        if (isset($data['type']) && $data['type'] == "option") {
            $html = option($data);
        } else {
            $html = select($data);
        }
    }
    return $html;
}

/**
 * vlaue为ID号的菜单
 *
 * @param $data = array(
 *              "type" => "输出类型：select，option",
 *              "sqlForm" => "数据库表名，可带查询条件和排序等",
 *              "sqlId" => "数据库表主键名称",
 *              "sqlField" => "需要作为option显示结果的数据库表字段名",
 *              'null'=> "禁用空选项",
 *              +函数select除option之外的所有参数
 *              );
 * @return string
 */
function idSelect($data): string
{
    $con = $GLOBALS['con'];
    if (empty($data['sqlField'])) {
        $html = "排重关键字段名称为空";
    } elseif (empty($data['sqlForm'])) {
        $html = "数据库查询语句为空";
    } elseif (empty($data['sqlId'])) {
        $html = "数据库主键字段名称为空";
    } else {
        $sqlId    = $data['sqlId'];
        $sqlField = $data['sqlField'];
        $sql      = mysqli_query($con, " select * from " . $data['sqlForm']);
        $option   = [];
        while ($array = mysqli_fetch_array($sql)) {
            $key          = $array[$sqlId];
            $option[$key] = $array[$sqlField];
        }
        unset($data['sqlId'], $data['sqlField'], $data['sqlForm']);
        $data['option'] = $option;
        if (isset($data['type']) && $data['type'] == "option") {
            $html = option($data);
        } else {
            $html = select($data);
        }
    }
    return $html;
}

/*所属区域关联下拉菜单
$regionId = "当前区域ID号"
*/
function regionSelect($regionId = "", $fieldName = 'area'): string
{
    $region = query("region", " id = '$regionId' ");
    return repeatSelect(["sqlForm" => "region GROUP BY `province` order by MAX(id)", "sqlField" => "province", "name" => "province", "title" => "省份", "value" => $region['province'], "change" => "regionProvince"]) .
        repeatSelect(["sqlForm" => "region where province = '$region[province]' ", "sqlField" => "city", "name" => "city", "title" => "城市", "value" => $region['city'], "change" => "regionCity"]) .
        idSelect(["sqlForm" => "region where province = '$region[province]' and city = '$region[city]' ", "sqlId" => "id", "sqlField" => "area", "name" => $fieldName, "title" => "区域", "value" => $region['id']]);
}

function spanButton(array $data): string
{
    $jsonParam = json_encode(getVal($data, 'para', []), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
    $json      = str_replace('"', '\'', $jsonParam ?: '{}');
    $params    = [
        'callback' => getVal($data, 'callback', 'layer'),
        'page'     => getVal($data, 'page', $_GET['cla'] ?? ''),
        'fun'      => getVal($data, 'fun', $_GET['addMx'] ?? ''),
        'json'     => $json,
        'style'    => getVal($data, 'style', 'spanButton'),
        'other'    => getVal($data, 'other', ''),
        'name'     => getVal($data, 'name', '新增'),
    ];
    // 是否是首个按钮
    if (getVal($data, 'first') === true) {
        $params['other'] .= ' style="margin-left:0"';
    }
    return sprintf(
        '<span class="%s" onclick="%s(\'%s\', \'%s\', %s)" %s>%s</span>',
        $params['style'],
        $params['callback'],
        $params['page'],
        $params['fun'],
        $params['json'],
        $params['other'],
        $params['name']
    );
}

/*图文混排的文章编辑
$data = array(
    "type" => "文章分类",
    "typeId" => "分类ID（如content表id，buyCar表id） ",
    "folder" => "存放图片的文件夹名称，在img/articleImg/下",
    "maxWidth" => "图片的最大宽度，超出则会缩放为此宽度",
);
*/
//变量解释：$Target为文章对象，$TargetName为文章对象的表名称，$TargetId为当前文章主人的id号,$imgurl为图片的子文件夹名称，$ImgMaxWidth为图片的最大宽度（超过此宽度则会缩放为此宽度）
function article($data): string
{
    $con  = $GLOBALS['con'];
    $html = "";
    $sql  = mysqli_query($con, " select * from article where type = '" . $data['type'] . "' and typeId = '" . $data['typeId'] . "' order by list ");
    if (mysqli_num_rows($sql) == 0) {
        $html .= "<div class='kuang'>没有任何内容</div>";
    } else {
        while ($array = mysqli_fetch_array($sql)) {
            if (empty($array['img'])) {
                $content = "<div articleWordContentId='" . $array['id'] . "' class='articleMx'>" . neirong($array['word']) . "</div>";
                $istype  = "word";
            } else {
                $content = "<div class='center'><img src='" . root . $array['img'] . "'></div>";
                $istype  = "img";
            }
            $html .= "
			<a name='" . $array['id'] . "'>
			<div class='kuang relative textIndent'>
				<div title='点击更新序列号' articleEditList='" . $array['list'] . "' isid='" . $array['id'] . "' class='articleList articleControl'>" . $array['list'] . "</div>
				<div articleEditType='" . $istype . "' isid='" . $array['id'] . "' class='articleEdit articleControl'>编辑这段</div>
				<a href='" . root . "library/libData.html?type=articleDelete&id=" . $array['id'] . "'><div class='articleDelete articleControl'>X</div></a>
				" . $content . "
			</div>
			</a>
			";
        }
    }
    $html .= "
	<!--窗口浮标开始-->
	<div id='addArticleWordButton'>
		<img src='" . root . "img/images/articleAddWord.png'>
		<p>添加一段文字</p>
	</div>
	<div id='addArticleImgButton'>
		<img src='" . root . "img/images/articleAddImg.png'>
		<p>添加一张图片</p>
	</div>
	<!--窗口浮标结束-->
	<!--文字编辑弹出层开始-->
	<div class='hide' id='articleWordEdit'>
		<div class='dibian'></div>
		<div class='win' style='height:596px; width:1200px; margin:-300px 0 0 -600px;'>
			<p class='winTitle'>文字编辑器<span class='winClose' onClick=\"$('#articleWordEdit').hide()\">×</span></p>
			<form name='articleWordForm'>
				<textarea name='word' class='textarea' style='height:506px; width:1190px; border:0;'></textarea>
				<input name='articleId' type='hidden'>
				<input name='type' type='hidden' value='" . $data['type'] . "'>
				<input name='typeId' type='hidden' value='" . $data['typeId'] . "'>
			</form>
			<p class='winFooter'><input type='button' class='button' value='提交文字' onclick=\"subForm('articleWordForm','" . root . "library/libData.html?type=articleWordEdit')\"></p>
		</div>
	</div>
	<!--文字编辑弹出层结束-->
	<!--更新序列号弹出层开始-->
	<div class='hide' id='articleListEdit'>
		<div class='dibian'></div>
		<div class='win' style='width:300px; height:127px; margin:-63px 0 0 -150px;'>
			<p class='winTitle'>更新段落序列号<span class='winClose' onClick=\"$('#articleListEdit').hide()\">×</span></p>
			<div class='padding'>
			<form name='articleListForm'>
			段落序列号：<input name='articleListText' type='text' class='text textPrice'>
			<input name='artcleListId' type='hidden'>
			</form>
			</div>
			<p class='winFooter'><input type='button' class='button' onclick=\"subForm('articleListForm','" . root . "library/libData.html?type=articleListEdit')\" value='更新段落序列号'></p>
		</div>
	</div>
	<!--更新序列号弹出层结束-->
	<!--隐藏表单开始-->
	<div class='hide'>
	<form name='articleImgForm' method='post' action='" . root . "library/libData.html?type=articleImgEdit' enctype='multipart/form-data'>
		<input name='imgFile' type='file' onchange='document.articleImgForm.submit()' />
		<input name='id' type='hidden'>
		<input name='type' type='hidden' value='" . $data['type'] . "'>
		<input name='typeId' type='hidden' value='" . $data['typeId'] . "'>
		<input name='folder' type='hidden' value='" . $data['folder'] . "'>
		<input name='maxWidth' type='hidden' value='" . $data['maxWidth'] . "'>
	</form>
	</div>
	<!--隐藏表单结束-->
	<script>
	$(function(){
		//新增文字段落
		$('#addArticleWordButton').click(function(){
			$('#articleWordEdit').show();
			document.articleWordForm.word.value = '';
			document.articleWordForm.articleId.value = '';
		});

		//新增图片
		$('#addArticleImgButton').click(function(){
			document.articleImgForm.imgFile.click();
			document.articleImgForm.id.value = '';
		});
		//编辑已有段落
		$('[articleEditType]').click(function(){
			if($(this).attr('articleEditType') === 'word'){
				$('#articleWordEdit').show();
				let articleId = $(this).attr('isid');
				document.articleWordForm.articleId.value= articleId;
				$.post('" . root . "library/libData.html?type=getArticleText',{articleId:articleId},function(data){
					document.articleWordForm.word.value = data.word;
				},'json');
			}else{
				document.articleImgForm.imgFile.click();
				document.articleImgForm.id.value= $(this).attr('isid');
			}
		});
		//弹出序列号编辑层
		$('[articleEditList]').click(function(){
			$('#articleListEdit').show();
			document.articleListForm.articleListText.value = $(this).attr('articleEditList');
			document.articleListForm.artcleListId.value = $(this).attr('isid');
		});
	});
	</script>
	";
    return $html;
}


/*警示弹出层*/
function warn($warn = ""): string
{
    $html = '';
    if (isset($_SESSION['warn'])) {
        $warn = $_SESSION['warn']; //接收session中的提示信息
        unset($_SESSION['warn']);
    } elseif (isset($_COOKIE['warn'])) {
        $warn = $_COOKIE['warn']; //接收session中的提示信息
        setcookie('warn', '');
    } elseif (isset($GLOBALS['warn'])) { //接收全局变量中的提示信息
        $warn = $GLOBALS['warn'];
    }
    if (isset($warn) && $warn) {
        $html = "<script>$(function(){warn('$warn')})</script>";
    }
    $html .= "
	<div class='hide' id='warn'>
	    <div class='dibian' style='z-index:100'></div>
		<div class='win' style=' width:300px;height:160px; margin:-80px 0 0 -150px;z-index:101;'>
			<p class='winTitle'>
				<span id='winTitle'>温馨提示</span>
				<span onclick=\"$('#warn').hide()\" class='winClose'>×</span>
			</p>
			<div id='warnWord'>无</div>
			<div id='warnSure' onclick=\"$('#warn').hide()\">确定</div>
			<div id='warnCancel' onclick=\"$('#warn').hide()\">取消</div>
		</div>
	</div>
	<script>move('warn')
	</script>
	";
    return $html;
}


/**
 * 过滤xss
 *
 * @param string $html
 * @return string
 */
function filterXss(string $html): string
{
    $searchs  = [
        '<',
        '>',
    ];
    $replaces = [
        '&lt;',
        '&gt;',
    ];
    preg_match_all("/<([^<]+)>/i", $html, $matches);
    if ($matches[1]) {
        $whiteTags  = 'img|a|font|div|table|tbody|caption|tr|td|th|br|p|b|strong|i|u|em|span|ol|ul|li|blockquote';
        $matches[1] = array_unique($matches[1]);
        foreach ($matches[1] as $value) {
            $searchs[]  = "&lt;" . $value . "&gt;";
            $value      = str_replace(['\\', '/*'], ['.', '/.'], $value);
            $filterTags = [
                'onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate',
                'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange',
                'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick',
                'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate',
                'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete',
                'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel',
                'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart',
                'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop',
                'onsubmit', 'onunload', 'javascript', 'script', 'eval', 'behaviour', 'expression', 'style', 'class',
            ];
            $filterStr  = implode('|', $filterTags);
            $value      = preg_replace(["/($filterStr)/i"], '.', $value);

            if (!preg_match("/^[\/|\s]?($whiteTags)(\s+|$)/is", $value)) {
                $value = '';
            }
            $replaces[] = empty($value) ? '' : "<" . str_replace('&quot;', '"', $value) . ">";
        }
    }
    return str_replace($searchs, $replaces, $html);
}

/**
 * 与formSubArray()对应相反，此为过滤主方法，将HTML 实体转换为字符，其他格式内容保留不动.
 * @param $data object|array|bool|int|mixed|string
 * @return object|array|bool|int|mixed|string
 */
function formSubArrayDecode($data)
{
    $result = [];
    if (is_object($data)) {
        foreach ($data as $key => $value) {
            if (is_array($value) || is_object($value)) {
                $result[$key] = formSubArrayDecode($value);
            } else {
                $result[$key] = formSubDecode($value);
            }
        }
    } else if (is_array($data)) {
        foreach ($data as $key => $value) {
            if (is_array($value) || is_object($value)) {
                $result[$key] = formSubArrayDecode($value);
            } else {
                $result[$key] = formSubDecode($value);
            }
        }
    } else {
        $result = formSubDecode($data);
    }
    return $result;
}

//与formSub()对应相反，此为核心处理方法，将HTML 实体转换为字符，其他格式内容保留不动.
function formSubDecode($string)
{
    if (is_bool($string) || is_numeric($string) || $string === null) {
    } else {
        $string = html_entity_decode($string, ENT_QUOTES);
    }
    return $string;
}

/**
 * 只读文本框（可提交，赋值，自适应宽度）
 *
 * @param array $data
 *   $data = array(
 *   "name" => "文本框name",
 *   "id" => "文本框id",
 *   "data" => [] //生成data-key 参数 用于单个文本域更新时
 *   "title" => "文本框标题",
 *   "value" => "文本框value",
 *   "class" => "文本框的class",
 *   "click" => "鼠标点击事件函数名",
 *   "other" => "串联其他属性",
 *   );
 * @return string
 */
function readOnlyInput(array $data): string
{
    $data['id']    = $data['id'] ?? suiji();
    $data['class'] = 'readOnlyInput';
    $data['other'] = 'readonly';
    $html          = text($data);
    $js            = "<script>
                $(document).ready(function() {
                  // 获取输入框元素
                  var input = $('#{$data['id']}');
                  // 设置一个临时span来计算内容宽度
                  var tempSpan = $('<span>').css({
                    'position': 'absolute',
                    'top': '-9999px',
                    'left': '-9999px',
                    'white-space': 'nowrap',
                    'font-size': input.css('font-size'), // 继承输入框的字体大小
                    'font-family': input.css('font-family') // 继承输入框的字体
                  }).appendTo('body');
                
                  // 监听input值的变化
                  input.on('input', function() {
                    // 设置临时span的内容为输入框的值，并获取其宽度
                    tempSpan.text($(this).val());
                    var width = tempSpan.width();
                    
                    // 将输入框的宽度设置为临时span的宽度
                    input.width(width);
                  });
                
                  // 初始状态下，根据输入框的默认值设置宽度
                  input.trigger('input');
                });
            </script>";
    return $html . $js . "\n";
}

/*如果文字过多就显示pre*/
function pre($word)
{
    if (!empty($word) and mb_strlen($word, "UTF8") > 100) {
        return "<pre>" . $word . "</pre>";
    } else {
        return preg_replace(["/\n/"], ["<br>"], $word);
    }
}
